<template>
  <div class="app-container">
    <!-- 顶部导航栏 -->
    <header class="header">
      <div class="header-left">
        <div class="logo">
          <img 
            src="https://www.nenu.edu.cn/images/logo.png" 
            alt="东北师范大学LOGO" 
            class="logo-img"
          />
        </div>
        <h1 class="platform-title">东北师范大学古地图复原虚拟仿真平台</h1>
      </div>
      <div class="header-right">
        <!-- 当前显示状态 -->
        <div v-if="currentDisplayType" class="current-display">
          <span class="display-label">当前显示：</span>
          <div class="display-icon">
            <svg v-if="currentDisplayType === 'point'" width="16" height="16" viewBox="0 0 16 16">
              <circle cx="8" cy="8" r="4" fill="#F5DEB3" stroke="#D4AF37" stroke-width="1"/>
            </svg>
            <svg v-else-if="currentDisplayType === 'line'" width="16" height="16" viewBox="0 0 16 16">
              <path d="M2 8 L6 4 L10 6 L14 2" stroke="#F5DEB3" stroke-width="2" fill="none"/>
            </svg>
            <svg v-else-if="currentDisplayType === 'area'" width="16" height="16" viewBox="0 0 16 16">
              <polygon points="8,2 14,12 2,12" fill="#F5DEB3" opacity="0.6" stroke="#D4AF37" stroke-width="1"/>
            </svg>
          </div>
          <span class="display-text">
            {{ currentDisplayType === 'point' ? '点显示' : 
               currentDisplayType === 'line' ? '线显示' : '面显示' }}
          </span>
        </div>
        
        <el-button 
          type="primary" 
          @click="showDataDialog = true"
          class="analysis-btn"
        >
          <el-icon><Search /></el-icon>
          时空分析制作
        </el-button>
        
        <el-button 
          @click="showReproductionDialog = true"
          class="reproduction-btn"
        >
          <el-icon><Clock /></el-icon>
          时空复现
        </el-button>
        
        <div class="user-info">
          <el-avatar :size="32" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" />
          <span class="username">admin</span>
        </div>
      </div>
    </header>

    <!-- 主内容区 -->
    <main class="main-content">
      <!-- 左侧地图区域 -->
      <div class="map-container">
        <div id="map" class="map"></div>
        <!-- 地图上的数据点显示 -->
        <div v-if="displayPoints.length > 0" class="map-overlay">
          <div 
            v-for="point in displayPoints" 
            :key="point.id"
            class="map-point"
            :style="{
              left: point.x + 'px',
              top: point.y + 'px',
              backgroundColor: point.color,
              clipPath: getShapeClipPath(point.shape)
            }"
            :title="point.name"
          ></div>
        </div>
      </div>

      <!-- 右侧选框区域 -->
      <div class="sidebar">
        <!-- 待分组数据区 -->
        <div class="pending-data-section">
          <div class="section-header">
            <h4>待分组数据</h4>
            <div class="header-actions">
              <el-button 
                type="primary" 
                size="small" 
                @click="showDetailDialog = true"
                :disabled="pendingData.length === 0"
                class="detail-btn"
              >
                <el-icon><View /></el-icon>
                详情
              </el-button>
              <span class="data-count">{{ pendingData.length }}条</span>
            </div>
          </div>
          <div class="pending-data-list">
            <div 
              v-for="item in pendingData" 
              :key="item.序号"
              class="pending-data-item"
              :class="{ selected: selectedPendingData.includes(item) }"
              @click="togglePendingDataSelection(item)"
              :title="getDataItemTooltip(item)"
            >
              <el-checkbox 
                :model-value="selectedPendingData.includes(item)"
                @change="togglePendingDataSelection(item)"
                @click.stop
              />
              <span class="item-name">{{ item.保护单位名称 }}</span>
            </div>
          </div>
        </div>

        <!-- 数据分组管理 -->
        <div class="groups-section">
          <div class="section-header">
            <h4>数据分组管理</h4>
            <el-button type="primary" size="small" @click="addGroup">添加分组</el-button>
          </div>
          
          <div class="groups-container">
            <div v-for="(group, groupIndex) in dataGroups" :key="group.id" class="group-item">
              <div class="group-header">
                <el-input 
                  v-model="group.name" 
                  size="small" 
                  placeholder="分组名称"
                  class="group-name-input"
                />
                <div class="group-controls">
                  <el-button 
                    size="small" 
                    @click="moveGroup(groupIndex, -1)"
                    :disabled="groupIndex === 0"
                  >
                    <el-icon><ArrowUp /></el-icon>
                  </el-button>
                  <el-button 
                    size="small" 
                    @click="moveGroup(groupIndex, 1)"
                    :disabled="groupIndex === dataGroups.length - 1"
                  >
                    <el-icon><ArrowDown /></el-icon>
                  </el-button>
                  <el-button 
                    size="small" 
                    type="danger" 
                    @click="removeGroup(groupIndex)"
                  >
                    <el-icon><Delete /></el-icon>
                  </el-button>
                </div>
              </div>
              
              <div class="subgroups-container">
                <div v-for="(subgroup, subIndex) in group.subgroups" :key="subgroup.id" class="subgroup-item">
                  <div class="subgroup-header">
                    <el-input 
                      v-model="subgroup.name" 
                      size="small" 
                      placeholder="子分组名称"
                      class="subgroup-name-input"
                    />
                    <div class="subgroup-style">
                      <el-select v-model="subgroup.shape" size="small" style="width: 80px;">
                        <el-option label="●" value="circle" />
                        <el-option label="■" value="square" />
                        <el-option label="▲" value="triangle" />
                        <el-option label="★" value="star" />
                        <el-option label="◆" value="diamond" />
                      </el-select>
                      <el-color-picker v-model="subgroup.color" size="small" />
                    </div>
                    <div class="subgroup-controls">
                      <el-button 
                        size="small" 
                        @click="moveSubgroup(groupIndex, subIndex, -1)"
                        :disabled="subIndex === 0"
                      >
                        <el-icon><ArrowUp /></el-icon>
                      </el-button>
                      <el-button 
                        size="small" 
                        @click="moveSubgroup(groupIndex, subIndex, 1)"
                        :disabled="subIndex === group.subgroups.length - 1"
                      >
                        <el-icon><ArrowDown /></el-icon>
                      </el-button>
                      <el-button 
                        size="small" 
                        type="danger" 
                        @click="removeSubgroup(groupIndex, subIndex)"
                      >
                        <el-icon><Delete /></el-icon>
                      </el-button>
                    </div>
                  </div>
                  
                  <div class="subgroup-data">
                    <div v-for="(item, itemIndex) in subgroup.data" :key="item.序号" class="data-item" :title="getDataItemTooltip(item)">
                      <span class="item-name">{{ item.保护单位名称 }}</span>
                      <div class="item-controls">
                        <el-button 
                          size="small" 
                          @click="moveDataInSubgroup(groupIndex, subIndex, itemIndex, -1)"
                          :disabled="itemIndex === 0"
                          class="move-btn"
                        >
                          <el-icon><ArrowUp /></el-icon>
                        </el-button>
                        <el-button 
                          size="small" 
                          @click="moveDataInSubgroup(groupIndex, subIndex, itemIndex, 1)"
                          :disabled="itemIndex === subgroup.data.length - 1"
                          class="move-btn"
                        >
                          <el-icon><ArrowDown /></el-icon>
                        </el-button>
                        <el-button 
                          size="small" 
                          type="text" 
                          @click="removeDataFromSubgroup(groupIndex, subIndex, item)"
                          class="remove-data-btn"
                        >
                          <el-icon><Close /></el-icon>
                        </el-button>
                      </div>
                    </div>
                  </div>
                  
                  <el-button 
                    type="text" 
                    size="small" 
                    @click="addDataToSubgroup(groupIndex, subIndex)"
                    class="add-data-btn"
                    :disabled="selectedPendingData.length === 0"
                  >
                    + 添加选中数据 ({{ selectedPendingData.length }})
                  </el-button>
                </div>
                
                <el-button 
                  type="text" 
                  size="small" 
                  @click="addSubgroup(groupIndex)"
                  class="add-subgroup-btn"
                >
                  + 添加子分组
                </el-button>
              </div>
            </div>
          </div>
        </div>
        
        <div class="sidebar-footer">
          <el-button type="primary" @click="showDisplayDialog = true" :disabled="!hasData">
            <el-icon><Setting /></el-icon>
            设定展示形式
          </el-button>
          <div class="submit-button-container">
            <el-button 
              type="primary" 
              @click="submitToMap" 
              :disabled="!canSubmit"
              class="submit-btn"
            >
              <el-icon><Check /></el-icon>
              <span>提交显示</span>
            </el-button>
          </div>
        </div>
      </div>
    </main>

    <!-- 数据选择对话框 -->
    <el-dialog 
      v-model="showDataDialog" 
      title="数据筛选与分析" 
      width="85%"
      :before-close="handleDataDialogClose"
      class="data-dialog"
    >
      <div class="data-dialog-content">
        <div class="filter-section">
          <h4 class="section-title">
            <el-icon><Filter /></el-icon>
            筛选条件
          </h4>
          <div class="filter-controls">
            <el-row :gutter="16">
              <el-col :span="4">
                <div class="filter-item">
                  <label>保护单位名称</label>
                  <el-select v-model="filters.保护单位名称" placeholder="请选择" clearable>
                    <el-option v-for="item in getUniqueValues('保护单位名称')" :key="item" :label="item" :value="item" />
                  </el-select>
                </div>
              </el-col>
              <el-col :span="4">
                <div class="filter-item">
                  <label>公布批次</label>
                  <el-select v-model="filters.公布批次" placeholder="请选择" clearable>
                    <el-option v-for="item in getUniqueValues('公布批次')" :key="item" :label="item" :value="item" />
                  </el-select>
                </div>
              </el-col>
              <el-col :span="4">
                <div class="filter-item">
                  <label>类别</label>
                  <el-select v-model="filters.类别" placeholder="请选择" clearable>
                    <el-option v-for="item in getUniqueValues('类别')" :key="item" :label="item" :value="item" />
                  </el-select>
                </div>
              </el-col>
              <el-col :span="4">
                <div class="filter-item">
                  <label>年代</label>
                  <el-select v-model="filters.年代" placeholder="请选择" clearable>
                    <el-option v-for="item in getUniqueValues('年代')" :key="item" :label="item" :value="item" />
                  </el-select>
                </div>
              </el-col>
              <el-col :span="4">
                <div class="filter-item">
                  <label>地点</label>
                  <el-select v-model="filters.地点" placeholder="请选择" clearable>
                    <el-option v-for="item in getUniqueValues('地点')" :key="item" :label="item" :value="item" />
                  </el-select>
                </div>
              </el-col>
              <el-col :span="4">
                <div class="filter-item">
                  <label>&nbsp;</label>
                  <el-button type="primary" @click="applyFilters" style="width: 100%;">
                    <el-icon><Search /></el-icon>
                    筛选
                  </el-button>
                </div>
              </el-col>
            </el-row>
          </div>
        </div>
        
        <div class="table-section">
          <h4 class="section-title">
            <el-icon><List /></el-icon>
            数据列表
            <span class="data-count">共 {{ filteredData.length }} 条</span>
          </h4>
          <el-table 
            :data="filteredData" 
            style="width: 100%;"
            max-height="450"
            @selection-change="handleSelectionChange"
            stripe
            border
          >
            <el-table-column type="selection" width="55" />
            <el-table-column prop="序号" label="序号" width="80" align="center" />
            <el-table-column prop="保护单位名称" label="保护单位名称" min-width="200" show-overflow-tooltip />
            <el-table-column prop="公布批次" label="公布批次" width="120" align="center" />
            <el-table-column prop="类别" label="类别" width="100" align="center" />
            <el-table-column prop="年代" label="年代" width="120" align="center" />
            <el-table-column prop="地点" label="地点" min-width="150" show-overflow-tooltip />
            <el-table-column prop="东经" label="东经" width="120" align="center" />
            <el-table-column prop="北纬" label="北纬" width="120" align="center" />
          </el-table>
        </div>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showDataDialog = false" size="large">
            <el-icon><Close /></el-icon>
            取消
          </el-button>
          <el-button type="primary" @click="confirmDataSelection" size="large">
            <el-icon><Check /></el-icon>
            确定选择 ({{ selectedData.length }} 条)
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 展示形式设置对话框 -->
    <el-dialog 
      v-model="showDisplayDialog" 
      title="设定展示形式" 
      width="600px"
      class="display-dialog"
    >
      <div class="display-options">
        <h4 class="section-title">
          <el-icon><Setting /></el-icon>
          选择展示方式
        </h4>
        <div class="display-radio-group">
          <div 
            v-for="option in displayOptions" 
            :key="option.value"
            class="display-option"
            :class="{ 'is-checked': displayType === option.value }"
            @click="displayType = option.value"
          >
            <div class="option-content">
              <div class="option-radio">
                <el-radio 
                  v-model="displayType" 
                  :label="option.value"
                  @click.stop
                />
              </div>
              <div class="option-icon">
                <svg width="50" height="50" viewBox="0 0 50 50">
                  <g v-html="option.icon"></g>
                </svg>
              </div>
              <div class="option-text">
                <div class="option-title">{{ option.title }}</div>
                <div class="option-desc">{{ option.desc }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showDisplayDialog = false" size="large">
            <el-icon><Close /></el-icon>
            取消
          </el-button>
          <el-button type="primary" @click="submitDisplay" size="large">
            <el-icon><Check /></el-icon>
            确定设置
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 待分组数据详情对话框 -->
    <el-dialog 
      v-model="showDetailDialog" 
      title="待分组数据详情" 
      width="90%"
      class="detail-dialog"
    >
      <div class="detail-dialog-content">
        <div class="detail-table-section">
          <h4 class="section-title">
            <el-icon><List /></el-icon>
            数据详情
            <span class="data-count">共 {{ pendingData.length }} 条</span>
          </h4>
          <el-table 
            :data="sortedPendingData" 
            style="width: 100%;"
            max-height="500"
            @selection-change="handleDetailSelectionChange"
            stripe
            border
          >
            <el-table-column type="selection" width="55" />
            <el-table-column 
              prop="序号" 
              label="序号" 
              width="80" 
              align="center" 
              sortable
              @click="handleSort('序号')"
            />
            <el-table-column 
              prop="保护单位名称" 
              label="保护单位名称" 
              min-width="200" 
              show-overflow-tooltip
              sortable
              @click="handleSort('保护单位名称')"
            />
            <el-table-column 
              prop="公布批次" 
              label="公布批次" 
              width="120" 
              align="center"
              sortable
              @click="handleSort('公布批次')"
            />
            <el-table-column 
              prop="类别" 
              label="类别" 
              width="100" 
              align="center"
              sortable
              @click="handleSort('类别')"
            />
            <el-table-column 
              prop="年代" 
              label="年代" 
              width="120" 
              align="center"
              sortable
              @click="handleSort('年代')"
            />
            <el-table-column 
              prop="地点" 
              label="地点" 
              min-width="150" 
              show-overflow-tooltip
              sortable
              @click="handleSort('地点')"
            />
            <el-table-column 
              prop="东经" 
              label="东经" 
              width="120" 
              align="center"
              sortable
              @click="handleSort('东经')"
            />
            <el-table-column 
              prop="北纬" 
              label="北纬" 
              width="120" 
              align="center"
              sortable
              @click="handleSort('北纬')"
            />
          </el-table>
        </div>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showDetailDialog = false" size="large">
            <el-icon><Close /></el-icon>
            取消
          </el-button>
          <el-button type="primary" @click="confirmDetailSelection" size="large">
            <el-icon><Check /></el-icon>
            确定选择 ({{ detailSelectedData.length }} 条)
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 时空复现对话框 -->
    <el-dialog 
      v-model="showReproductionDialog" 
      title="时空复现" 
      width="80%"
      class="reproduction-dialog"
    >
      <div class="reproduction-content">
        <div class="student-selection">
          <h4 class="section-title">
            <el-icon><User /></el-icon>
            选择学生实验数据
          </h4>
          <el-select v-model="selectedStudentId" placeholder="请选择学生" style="width: 300px;" @change="loadStudentData">
            <el-option 
              v-for="student in mockStudentData" 
              :key="student.id" 
              :label="student.name" 
              :value="student.id"
            />
          </el-select>
        </div>
        
        <div v-if="selectedStudentData" class="student-data-preview">
          <h4 class="section-title">
            <el-icon><View /></el-icon>
            学生实验数据预览
          </h4>
          <div class="student-info">
            <p><strong>学生姓名：</strong>{{ selectedStudentData.name }}</p>
            <p><strong>提交时间：</strong>{{ selectedStudentData.submitTime }}</p>
            <p><strong>展示形式：</strong>{{ getDisplayTypeName(selectedStudentData.displayType) }}</p>
          </div>
          
          <div class="groups-preview">
            <div v-for="(group, groupIndex) in selectedStudentData.groups" :key="group.id" class="group-preview">
              <div class="group-header">
                <el-checkbox 
                  v-model="group.selected" 
                  @change="updateGroupSelection(groupIndex)"
                  class="group-checkbox"
                >
                  <strong>{{ group.name }}</strong>
                </el-checkbox>
              </div>
              
              <div class="subgroups-preview">
                <div v-for="subgroup in group.subgroups" :key="subgroup.id" class="subgroup-preview">
                  <div class="subgroup-info">
                    <span class="subgroup-name">{{ subgroup.name }}</span>
                    <span class="subgroup-meta">
                      <span class="color-indicator" :style="{ backgroundColor: subgroup.color }"></span>
                      <span class="shape-indicator">{{ getShapeName(subgroup.shape) }}</span>
                      <span class="data-count">({{ subgroup.data.length }}条数据)</span>
                    </span>
                  </div>
                  <div class="subgroup-data">
                    <el-tag 
                      v-for="item in subgroup.data.slice(0, 3)" 
                      :key="item.序号" 
                      size="small" 
                      style="margin-right: 5px; margin-bottom: 3px;"
                    >
                      {{ item.保护单位名称 }}
                    </el-tag>
                    <span v-if="subgroup.data.length > 3" class="more-data">等{{ subgroup.data.length }}条</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showReproductionDialog = false" size="large">
            <el-icon><Close /></el-icon>
            取消
          </el-button>
          <el-button type="primary" @click="reproduceStudentExperiment" size="large" :disabled="!hasSelectedGroups">
            <el-icon><Check /></el-icon>
            复现实验 ({{ selectedGroupsCount }} 个分组)
          </el-button>
        </div>
      </template>
    </el-dialog>


  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  User, 
  Filter, 
  Search, 
  List, 
  Close, 
  Check, 
  Setting,
  View,
  ArrowUp,
  ArrowDown,
  Delete,
  Clock
} from '@element-plus/icons-vue'
import L from 'leaflet'

// 数据类型定义
interface DataItem {
  序号: number
  保护单位名称: string
  公布批次: string
  类别: string
  年代: string
  地点: string
  东经: string
  北纬: string
}

interface Subgroup {
  id: string
  name: string
  shape: string
  color: string
  data: DataItem[]
}

interface Group {
  id: string
  name: string
  subgroups: Subgroup[]
}

interface DisplayPoint {
  id: string
  name: string
  x: number
  y: number
  color: string
  shape: string
}

// 学生实验数据类型定义
interface StudentExperimentData {
  id: string
  name: string
  submitTime: string
  displayType: string
  groups: (Group & { selected?: boolean })[]
}

// 响应式数据
const showDataDialog = ref(false)
const showDisplayDialog = ref(false)
const showDetailDialog = ref(false)
const showReproductionDialog = ref(false)
const displayType = ref('point')
const currentDisplayType = ref('')
const dataGroups = ref<Group[]>([])
const selectedData = ref<DataItem[]>([])
const displayPoints = ref<DisplayPoint[]>([])
const pendingData = ref<DataItem[]>([])
const selectedPendingData = ref<DataItem[]>([])
const detailSelectedData = ref<DataItem[]>([])
const sortField = ref('')
const sortOrder = ref<'asc' | 'desc'>('asc')

// 时空复现相关
const selectedStudentId = ref('')
const selectedStudentData = ref<StudentExperimentData | null>(null)

// 展示选项配置
const displayOptions = [
  {
    value: 'point',
    title: '点显示',
    desc: '在地图上显示各个数据点，按分组顺序依次展现',
    icon: `<circle cx="25" cy="25" r="15" fill="#409EFF" stroke="#fff" stroke-width="3"/>
           <circle cx="15" cy="15" r="8" fill="#67C23A" stroke="#fff" stroke-width="2"/>
           <circle cx="35" cy="18" r="5" fill="#E6A23C" stroke="#fff" stroke-width="2"/>
           <circle cx="18" cy="35" r="6" fill="#F56C6C" stroke="#fff" stroke-width="2"/>`
  },
  {
    value: 'line',
    title: '线显示',
    desc: '将同组数据按顺序连成线条，不同组使用不同颜色',
    icon: `<path d="M8 25 L15 15 L25 20 L35 12 L42 18" stroke="#409EFF" stroke-width="4" fill="none"/>
           <circle cx="8" cy="25" r="3" fill="#409EFF"/>
           <circle cx="15" cy="15" r="3" fill="#409EFF"/>
           <circle cx="25" cy="20" r="3" fill="#409EFF"/>
           <circle cx="35" cy="12" r="3" fill="#409EFF"/>
           <circle cx="42" cy="18" r="3" fill="#409EFF"/>`
  },
  {
    value: 'area',
    title: '面显示',
    desc: '将同组数据围成封闭区域，首尾相连形成多边形',
    icon: `<polygon points="25,10 40,30 10,30" fill="#409EFF" opacity="0.6" stroke="#409EFF" stroke-width="3"/>
           <circle cx="25" cy="10" r="3" fill="#409EFF"/>
           <circle cx="40" cy="30" r="3" fill="#409EFF"/>
           <circle cx="10" cy="30" r="3" fill="#409EFF"/>`
  }
]

// 筛选相关
const filters = reactive({
  保护单位名称: '',
  公布批次: '',
  类别: '',
  年代: '',
  地点: ''
})

// 模拟数据 - 东北地区50条文物保护单位数据
const mockData: DataItem[] = [
  { 序号: 1, 保护单位名称: '沈阳故宫', 公布批次: '第一批', 类别: '古建筑', 年代: '清代', 地点: '沈阳市沈河区', 东经: '123°26\'18.35"', 北纬: '41°47\'21.28"' },
  { 序号: 2, 保护单位名称: '清昭陵', 公布批次: '第一批', 类别: '古墓葬', 年代: '清代', 地点: '沈阳市皇姑区', 东经: '123°24\'46.6"', 北纬: '41°52\'30.61"' },
  { 序号: 3, 保护单位名称: '清福陵', 公布批次: '第一批', 类别: '古墓葬', 年代: '清代', 地点: '沈阳市东陵区', 东经: '123°31\'78"', 北纬: '41°47\'18.32"' },
  { 序号: 4, 保护单位名称: '长白山天池', 公布批次: '第二批', 类别: '自然遗产', 年代: '新石器时代', 地点: '延边朝鲜族自治州', 东经: '128°26\'55"', 北纬: '42°18\'51.47"' },
  { 序号: 5, 保护单位名称: '五女山山城', 公布批次: '第二批', 类别: '古建筑', 年代: '高句丽', 地点: '本溪市桓仁县', 东经: '125°52\'23"', 北纬: '41°21\'7.84"' },
  { 序号: 6, 保护单位名称: '集安高句丽王城', 公布批次: '第三批', 类别: '古建筑', 年代: '高句丽', 地点: '通化市集安市', 东经: '126°26\'23"', 北纬: '41°47\'34.62"' },
  { 序号: 7, 保护单位名称: '长春伪满皇宫', 公布批次: '第三批', 类别: '近现代重要史迹', 年代: '1932年', 地点: '长春市宽城区', 东经: '125°19\'28.97"', 北纬: '43°53\'12.88"' },
  { 序号: 8, 保护单位名称: '哈尔滨中央大街', 公布批次: '第四批', 类别: '近现代重要史迹', 年代: '1898年', 地点: '哈尔滨市道里区', 东经: '126°21\'58.81"', 北纬: '45°46\'13.33"' },
  { 序号: 9, 保护单位名称: '大连旅顺口', 公布批次: '第一批', 类别: '近现代重要史迹', 年代: '1898年', 地点: '大连市旅顺口区', 东经: '121°15\'32.45"', 北纬: '38°51\'24.67"' },
  { 序号: 10, 保护单位名称: '抚顺永陵', 公布批次: '第二批', 类别: '古墓葬', 年代: '明代', 地点: '抚顺市新宾县', 东经: '125°21\'45.23"', 北纬: '41°58\'12.34"' },
  { 序号: 11, 保护单位名称: '本溪水洞', 公布批次: '第三批', 类别: '自然遗产', 年代: '古生代', 地点: '本溪市本溪县', 东经: '123°42\'18.56"', 北纬: '41°17\'45.23"' },
  { 序号: 12, 保护单位名称: '丹东鸭绿江断桥', 公布批次: '第四批', 类别: '近现代重要史迹', 年代: '1909年', 地点: '丹东市振兴区', 东经: '124°23\'56.78"', 北纬: '40°07\'23.45"' },
  { 序号: 13, 保护单位名称: '锦州笔架山', 公布批次: '第二批', 类别: '自然遗产', 年代: '古生代', 地点: '锦州市太和区', 东经: '121°07\'34.12"', 北纬: '41°06\'45.67"' },
  { 序号: 14, 保护单位名称: '营口楞严寺', 公布批次: '第三批', 类别: '古建筑', 年代: '清代', 地点: '营口市站前区', 东经: '122°14\'23.89"', 北纬: '40°39\'56.12"' },
  { 序号: 15, 保护单位名称: '阜新海州露天矿', 公布批次: '第四批', 类别: '近现代重要史迹', 年代: '1953年', 地点: '阜新市海州区', 东经: '121°39\'45.23"', 北纬: '42°01\'34.56"' },
  { 序号: 16, 保护单位名称: '辽阳白塔', 公布批次: '第一批', 类别: '古建筑', 年代: '辽代', 地点: '辽阳市白塔区', 东经: '123°14\'56.78"', 北纬: '41°16\'23.45"' },
  { 序号: 17, 保护单位名称: '盘锦红海滩', 公布批次: '第五批', 类别: '自然遗产', 年代: '现代', 地点: '盘锦市大洼县', 东经: '121°41\'12.34"', 北纬: '40°51\'45.67"' },
  { 序号: 18, 保护单位名称: '铁岭银冈书院', 公布批次: '第三批', 类别: '古建筑', 年代: '清代', 地点: '铁岭市银州区', 东经: '123°51\'34.56"', 北纬: '42°17\'23.89"' },
  { 序号: 19, 保护单位名称: '朝阳凤凰山', 公布批次: '第二批', 类别: '古建筑', 年代: '辽代', 地点: '朝阳市双塔区', 东经: '120°27\'45.12"', 北纬: '41°34\'56.78"' },
  { 序号: 20, 保护单位名称: '葫芦岛兴城古城', 公布批次: '第一批', 类别: '古建筑', 年代: '明代', 地点: '葫芦岛市兴城市', 东经: '120°43\'23.45"', 北纬: '40°37\'12.34"' },
  { 序号: 21, 保护单位名称: '长春净月潭', 公布批次: '第四批', 类别: '自然遗产', 年代: '现代', 地点: '长春市净月区', 东经: '125°25\'34.67"', 北纬: '43°47\'56.23"' },
  { 序号: 22, 保护单位名称: '吉林文庙', 公布批次: '第二批', 类别: '古建筑', 年代: '清代', 地点: '吉林市昌邑区', 东经: '126°33\'45.89"', 北纬: '43°50\'12.45"' },
  { 序号: 23, 保护单位名称: '四平战役纪念馆', 公布批次: '第三批', 类别: '近现代重要史迹', 年代: '1946年', 地点: '四平市铁西区', 东经: '124°22\'56.78"', 北纬: '43°09\'34.12"' },
  { 序号: 24, 保护单位名称: '辽源魁星楼', 公布批次: '第四批', 类别: '古建筑', 年代: '清代', 地点: '辽源市龙山区', 东经: '125°08\'23.45"', 北纬: '42°53\'45.67"' },
  { 序号: 25, 保护单位名称: '通化玉皇山', 公布批次: '第二批', 类别: '古建筑', 年代: '明代', 地点: '通化市东昌区', 东经: '125°56\'34.56"', 北纬: '41°43\'12.89"' },
  { 序号: 26, 保护单位名称: '白山长白山', 公布批次: '第一批', 类别: '自然遗产', 年代: '古生代', 地点: '白山市抚松县', 东经: '127°42\'45.23"', 北纬: '42°24\'56.78"' },
  { 序号: 27, 保护单位名称: '松原查干湖', 公布批次: '第五批', 类别: '自然遗产', 年代: '现代', 地点: '松原市前郭县', 东经: '124°52\'12.34"', 北纬: '45°18\'45.67"' },
  { 序号: 28, 保护单位名称: '白城向海湿地', 公布批次: '第四批', 类别: '自然遗产', 年代: '现代', 地点: '白城市通榆县', 东经: '122°31\'23.89"', 北纬: '44°47\'34.56"' },
  { 序号: 29, 保护单位名称: '延边朝鲜族民俗村', 公布批次: '第三批', 类别: '民俗文化', 年代: '清代', 地点: '延边州和龙市', 东经: '129°15\'45.12"', 北纬: '42°32\'56.78"' },
  { 序号: 30, 保护单位名称: '哈尔滨索菲亚教堂', 公布批次: '第一批', 类别: '近现代重要史迹', 年代: '1907年', 地点: '哈尔滨市道里区', 东经: '126°37\'23.45"', 北纬: '45°46\'12.34"' },
  { 序号: 31, 保护单位名称: '齐齐哈尔扎龙湿地', 公布批次: '第二批', 类别: '自然遗产', 年代: '现代', 地点: '齐齐哈尔市铁锋区', 东经: '123°55\'34.67"', 北纬: '47°12\'45.89"' },
  { 序号: 32, 保护单位名称: '牡丹江镜泊湖', 公布批次: '第三批', 类别: '自然遗产', 年代: '古生代', 地点: '牡丹江市宁安市', 东经: '128°47\'56.23"', 北纬: '43°52\'34.56"' },
  { 序号: 33, 保护单位名称: '佳木斯三江口', 公布批次: '第四批', 类别: '自然遗产', 年代: '现代', 地点: '佳木斯市前进区', 东经: '130°22\'12.78"', 北纬: '46°48\'45.23"' },
  { 序号: 34, 保护单位名称: '大庆铁人纪念馆', 公布批次: '第五批', 类别: '近现代重要史迹', 年代: '1960年', 地点: '大庆市让胡路区', 东经: '125°06\'34.89"', 北纬: '46°35\'56.12"' },
  { 序号: 35, 保护单位名称: '鸡西虎头要塞', 公布批次: '第二批', 类别: '近现代重要史迹', 年代: '1934年', 地点: '鸡西市虎林市', 东经: '132°58\'23.45"', 北纬: '45°46\'12.67"' },
  { 序号: 36, 保护单位名称: '双鸭山七星河湿地', 公布批次: '第三批', 类别: '自然遗产', 年代: '现代', 地点: '双鸭山市宝清县', 东经: '131°15\'45.78"', 北纬: '46°19\'34.23"' },
  { 序号: 37, 保护单位名称: '伊春五营森林公园', 公布批次: '第四批', 类别: '自然遗产', 年代: '现代', 地点: '伊春市五营区', 东经: '129°12\'56.34"', 北纬: '48°06\'45.67"' },
  { 序号: 38, 保护单位名称: '七台河桃山湖', 公布批次: '第五批', 类别: '自然遗产', 年代: '现代', 地点: '七台河市桃山区', 东经: '130°58\'23.89"', 北纬: '45°46\'12.45"' },
  { 序号: 39, 保护单位名称: '鹤岗萝北口岸', 公布批次: '第三批', 类别: '近现代重要史迹', 年代: '1988年', 地点: '鹤岗市萝北县', 东经: '130°50\'34.56"', 北纬: '47°34\'56.78"' },
  { 序号: 40, 保护单位名称: '黑河瑷珲古城', 公布批次: '第一批', 类别: '古建筑', 年代: '清代', 地点: '黑河市爱辉区', 东经: '127°29\'45.12"', 北纬: '50°14\'23.89"' },
  { 序号: 41, 保护单位名称: '绥化林枫故居', 公布批次: '第四批', 类别: '近现代重要史迹', 年代: '1905年', 地点: '绥化市北林区', 东经: '126°59\'56.78"', 北纬: '46°38\'34.12"' },
  { 序号: 42, 保护单位名称: '大兴安岭呼中森林', 公布批次: '第二批', 类别: '自然遗产', 年代: '现代', 地点: '大兴安岭地区呼中区', 东经: '123°18\'12.45"', 北纬: '51°43\'56.23"' },
  { 序号: 43, 保护单位名称: '漠河北极村', 公布批次: '第五批', 类别: '自然遗产', 年代: '现代', 地点: '大兴安岭地区漠河市', 东经: '122°21\'34.67"', 北纬: '53°28\'45.89"' },
  { 序号: 44, 保护单位名称: '抚远东极广场', 公布批次: '第三批', 类别: '近现代重要史迹', 年代: '1984年', 地点: '佳木斯市抚远市', 东经: '134°18\'56.12"', 北纬: '48°22\'34.78"' },
  { 序号: 45, 保护单位名称: '同江三江口', 公布批次: '第四批', 类别: '自然遗产', 年代: '现代', 地点: '佳木斯市同江市', 东经: '132°30\'23.45"', 北纬: '47°39\'12.56"' },
  { 序号: 46, 保护单位名称: '富锦湿地公园', 公布批次: '第五批', 类别: '自然遗产', 年代: '现代', 地点: '佳木斯市富锦市', 东经: '132°02\'45.78"', 北纬: '47°15\'34.23"' },
  { 序号: 47, 保护单位名称: '饶河乌苏里江', 公布批次: '第二批', 类别: '自然遗产', 年代: '现代', 地点: '双鸭山市饶河县', 东经: '134°01\'56.89"', 北纬: '46°48\'12.34"' },
  { 序号: 48, 保护单位名称: '东宁要塞群', 公布批次: '第一批', 类别: '近现代重要史迹', 年代: '1935年', 地点: '牡丹江市东宁市', 东经: '131°07\'23.67"', 北纬: '44°04\'45.12"' },
  { 序号: 49, 保护单位名称: '穆棱河口湿地', 公布批次: '第三批', 类别: '自然遗产', 年代: '现代', 地点: '牡丹江市穆棱市', 东经: '130°31\'34.89"', 北纬: '44°55\'56.78"' },
  { 序号: 50, 保护单位名称: '海林横道河子', 公布批次: '第四批', 类别: '近现代重要史迹', 年代: '1903年', 地点: '牡丹江市海林市', 东经: '129°13\'45.23"', 北纬: '44°38\'12.56"' }
]

// 模拟学生实验数据
const mockStudentData: StudentExperimentData[] = [
  {
    id: 'student1',
    name: '张三',
    submitTime: '2024-01-15 14:30:00',
    displayType: 'point',
    groups: [
      {
        id: 'group1',
        name: '清代建筑',
        selected: false,
        subgroups: [
          {
            id: 'sub1',
            name: '皇家建筑',
            color: '#409EFF',
            shape: 'circle',
            data: [mockData[0], mockData[1], mockData[2]] // 沈阳故宫、清昭陵、清福陵
          },
          {
            id: 'sub2',
            name: '宗教建筑',
            color: '#67C23A',
            shape: 'square',
            data: [mockData[13], mockData[21]] // 营口楞严寺、吉林文庙
          }
        ]
      },
      {
        id: 'group2',
        name: '自然遗产',
        selected: false,
        subgroups: [
          {
            id: 'sub3',
            name: '山水景观',
            color: '#E6A23C',
            shape: 'triangle',
            data: [mockData[3], mockData[10], mockData[25]] // 长白山天池、本溪水洞、白山长白山
          }
        ]
      }
    ]
  },
  {
    id: 'student2',
    name: '李四',
    submitTime: '2024-01-16 09:15:00',
    displayType: 'line',
    groups: [
      {
        id: 'group3',
        name: '近现代史迹',
        selected: false,
        subgroups: [
          {
            id: 'sub4',
            name: '抗战遗址',
            color: '#F56C6C',
            shape: 'star',
            data: [mockData[8], mockData[11], mockData[34]] // 大连旅顺口、丹东鸭绿江断桥、鸡西虎头要塞
          },
          {
            id: 'sub5',
            name: '工业遗产',
            color: '#909399',
            shape: 'diamond',
            data: [mockData[14], mockData[33]] // 阜新海州露天矿、大庆铁人纪念馆
          }
        ]
      }
    ]
  },
  {
    id: 'student3',
    name: '王五',
    submitTime: '2024-01-17 16:45:00',
    displayType: 'area',
    groups: [
      {
        id: 'group4',
        name: '古代建筑群',
        selected: false,
        subgroups: [
          {
            id: 'sub6',
            name: '高句丽遗址',
            color: '#C71585',
            shape: 'circle',
            data: [mockData[4], mockData[5]] // 五女山山城、集安高句丽王城
          },
          {
            id: 'sub7',
            name: '明清古城',
            color: '#FF6347',
            shape: 'square',
            data: [mockData[19], mockData[39]] // 葫芦岛兴城古城、黑河瑷珲古城
          }
        ]
      }
    ]
  },
  {
    id: 'student4',
    name: '赵六',
    submitTime: '2024-01-18 10:20:00',
    displayType: 'point',
    groups: [
      {
        id: 'group5',
        name: '辽宁文物',
        selected: false,
        subgroups: [
          {
            id: 'sub8',
            name: '沈阳地区',
            color: '#8A2BE2',
            shape: 'star',
            data: [mockData[0], mockData[6], mockData[12]] // 沈阳故宫、沈阳北陵、抚顺永陵
          },
          {
            id: 'sub9',
            name: '大连地区',
            color: '#FF1493',
            shape: 'diamond',
            data: [mockData[8], mockData[9]] // 大连旅顺口、大连金石滩
          }
        ]
      },
      {
        id: 'group6',
        name: '工业遗产',
        selected: false,
        subgroups: [
          {
            id: 'sub10',
            name: '重工业',
            color: '#32CD32',
            shape: 'circle',
            data: [mockData[14], mockData[15]] // 阜新海州露天矿、本溪湖工业遗产群
          }
        ]
      }
    ]
  },
  {
    id: 'student5',
    name: '钱七',
    submitTime: '2024-01-19 15:45:00',
    displayType: 'line',
    groups: [
      {
        id: 'group7',
        name: '吉林文化线路',
        selected: false,
        subgroups: [
          {
            id: 'sub11',
            name: '长春-吉林线',
            color: '#FF4500',
            shape: 'triangle',
            data: [mockData[20], mockData[21], mockData[22]] // 长春伪满皇宫、吉林文庙、吉林北山
          },
          {
            id: 'sub12',
            name: '延边朝鲜族线',
            color: '#4169E1',
            shape: 'square',
            data: [mockData[23], mockData[24]] // 延吉朝鲜族民俗村、图们江国境铁路大桥
          }
        ]
      }
    ]
  },
  {
    id: 'student6',
    name: '孙八',
    submitTime: '2024-01-20 11:30:00',
    displayType: 'area',
    groups: [
      {
        id: 'group8',
        name: '黑龙江保护区',
        selected: false,
        subgroups: [
          {
            id: 'sub13',
            name: '哈尔滨区域',
            color: '#DC143C',
            shape: 'circle',
            data: [mockData[30], mockData[31], mockData[32], mockData[35]] // 哈尔滨圣索菲亚教堂、哈尔滨中央大街、哈尔滨防洪纪念塔、哈尔滨极乐寺
          },
          {
            id: 'sub14',
            name: '大庆区域',
            color: '#228B22',
            shape: 'diamond',
            data: [mockData[33], mockData[36]] // 大庆铁人纪念馆、大庆油田历史陈列馆
          }
        ]
      }
    ]
  },
  {
    id: 'student7',
    name: '周九',
    submitTime: '2024-01-21 13:15:00',
    displayType: 'point',
    groups: [
      {
        id: 'group9',
        name: '边境文化',
        selected: false,
        subgroups: [
          {
            id: 'sub15',
            name: '中朝边境',
            color: '#FF6347',
            shape: 'star',
            data: [mockData[11], mockData[24]] // 丹东鸭绿江断桥、图们江国境铁路大桥
          },
          {
            id: 'sub16',
            name: '中俄边境',
            color: '#4682B4',
            shape: 'triangle',
            data: [mockData[39], mockData[46]] // 黑河瑷珲古城、饶河乌苏里江
          }
        ]
      },
      {
        id: 'group10',
        name: '自然与文化',
        selected: false,
        subgroups: [
          {
            id: 'sub17',
            name: '湿地保护',
            color: '#20B2AA',
            shape: 'circle',
            data: [mockData[46], mockData[48]] // 饶河乌苏里江、穆棱河口湿地
          }
        ]
      }
    ]
  },
  {
    id: 'student8',
    name: '吴十',
    submitTime: '2024-01-22 09:00:00',
    displayType: 'line',
    groups: [
      {
        id: 'group11',
        name: '铁路文化遗产',
        selected: false,
        subgroups: [
          {
            id: 'sub18',
            name: '中东铁路',
            color: '#B8860B',
            shape: 'square',
            data: [mockData[31], mockData[49], mockData[37]] // 哈尔滨中央大街、海林横道河子、齐齐哈尔昂昂溪
          }
        ]
      }
    ]
  }
]

const filteredData = ref<DataItem[]>([...mockData])

// 计算属性
const hasData = computed(() => {
  return dataGroups.value.some(group => 
    group.subgroups.some(subgroup => subgroup.data.length > 0)
  )
})

const canSubmit = computed(() => {
  return hasData.value && currentDisplayType.value
})

const sortedPendingData = computed(() => {
  if (!sortField.value) return pendingData.value
  
  return [...pendingData.value].sort((a, b) => {
    const aValue = a[sortField.value as keyof DataItem]
    const bValue = b[sortField.value as keyof DataItem]
    
    if (sortOrder.value === 'asc') {
      return aValue > bValue ? 1 : -1
    } else {
      return aValue < bValue ? 1 : -1
    }
  })
})

// 时空复现相关计算属性
const hasSelectedGroups = computed(() => {
  return selectedStudentData.value?.groups.some(group => group.selected) || false
})

const selectedGroupsCount = computed(() => {
  return selectedStudentData.value?.groups.filter(group => group.selected).length || 0
})

// 地图相关
let map: L.Map | null = null
let baseLayer: L.TileLayer | null = null
let dataLayers: L.Layer[] = []

// 方法
const initMap = () => {
  nextTick(() => {
    if (map) {
      map.remove()
    }
    
    map = L.map('map', {
      center: [45.0, 125.0],
      zoom: 6,
      zoomControl: true
    })

    // 添加古地图图层（这里使用OpenStreetMap作为示例）
    baseLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    })
    baseLayer.addTo(map)
  })
}

const getUniqueValues = (field: keyof DataItem) => {
  return [...new Set(mockData.map(item => item[field]))]
}

const applyFilters = () => {
  filteredData.value = mockData.filter(item => {
    return Object.entries(filters).every(([key, value]) => {
      if (!value) return true
      return item[key as keyof DataItem] === value
    })
  })
}

const handleSelectionChange = (selection: DataItem[]) => {
  selectedData.value = selection
}

const confirmDataSelection = () => {
  if (selectedData.value.length === 0) {
    ElMessage.warning('请选择要添加的数据')
    return
  }
  
  const addedCount = selectedData.value.length
  
  // 将选中的数据添加到待分组数据区
  selectedData.value.forEach(item => {
    if (!pendingData.value.find(p => p.序号 === item.序号)) {
      pendingData.value.push(item)
    }
  })
  
  showDataDialog.value = false
  selectedData.value = []
  ElMessage.success(`已添加 ${addedCount} 条数据到待分组区域`)
}

const handleDataDialogClose = () => {
  selectedData.value = []
}

const addGroup = () => {
  const newGroup: Group = {
    id: Date.now().toString(),
    name: `分组${dataGroups.value.length + 1}`,
    subgroups: []
  }
  dataGroups.value.push(newGroup)
}

const removeGroup = (index: number) => {
  dataGroups.value.splice(index, 1)
}

const moveGroup = (index: number, direction: number) => {
  const newIndex = index + direction
  if (newIndex >= 0 && newIndex < dataGroups.value.length) {
    const temp = dataGroups.value[index]
    dataGroups.value[index] = dataGroups.value[newIndex]
    dataGroups.value[newIndex] = temp
  }
}

const addSubgroup = (groupIndex: number) => {
  // 预定义的颜色和形状数组
  const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#C71585', '#FF6347', '#32CD32', '#8A2BE2', '#FF1493']
  const shapes = ['circle', 'square', 'triangle', 'star', 'diamond']
  
  // 计算当前所有子分组的总数，用于确定默认颜色和形状
  let totalSubgroups = 0
  dataGroups.value.forEach(group => {
    totalSubgroups += group.subgroups.length
  })
  
  const newSubgroup: Subgroup = {
    id: Date.now().toString(),
    name: `子分组${dataGroups.value[groupIndex].subgroups.length + 1}`,
    shape: shapes[totalSubgroups % shapes.length],
    color: colors[totalSubgroups % colors.length],
    data: []
  }
  dataGroups.value[groupIndex].subgroups.push(newSubgroup)
}

const removeSubgroup = (groupIndex: number, subIndex: number) => {
  dataGroups.value[groupIndex].subgroups.splice(subIndex, 1)
}

const moveSubgroup = (groupIndex: number, subIndex: number, direction: number) => {
  const subgroups = dataGroups.value[groupIndex].subgroups
  const newIndex = subIndex + direction
  if (newIndex >= 0 && newIndex < subgroups.length) {
    const temp = subgroups[subIndex]
    subgroups[subIndex] = subgroups[newIndex]
    subgroups[newIndex] = temp
  }
}

const getDataItemTooltip = (item: DataItem) => {
  return `${item.保护单位名称} - ${item.地点} (${item.东经}, ${item.北纬})`
}

const getShapeClipPath = (shape: string) => {
  switch (shape) {
    case 'circle':
      return 'circle(50%)'
    case 'square':
      return 'none'
    case 'triangle':
      return 'polygon(50% 0%, 0% 100%, 100% 100%)'
    case 'star':
      return 'polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%)'
    case 'diamond':
      return 'polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)'
    default:
      return 'none'
  }
}

// 经纬度解析函数
const parseCoordinate = (coordStr: string): number => {
  if (!coordStr) return NaN
  
  // 移除所有非数字和小数点的字符，但保留度分秒符号进行解析
  const cleanStr = coordStr.toString().trim()
  
  // 检查是否包含度分秒格式 (例: 123°26'18.35")
  const dmsMatch = cleanStr.match(/(\d+)°(\d+)'([\d.]+)"?/)
  if (dmsMatch) {
    const degrees = parseFloat(dmsMatch[1])
    const minutes = parseFloat(dmsMatch[2])
    const seconds = parseFloat(dmsMatch[3])
    return degrees + minutes/60 + seconds/3600
  }
  
  // 检查是否包含度分格式 (例: 123°26.5')
  const dmMatch = cleanStr.match(/(\d+)°([\d.]+)'?/)
  if (dmMatch) {
    const degrees = parseFloat(dmMatch[1])
    const minutes = parseFloat(dmMatch[2])
    return degrees + minutes/60
  }
  
  // 简单的度格式 (例: 123.45° 或 123.45)
  const simpleMatch = cleanStr.match(/([\d.]+)/)
  if (simpleMatch) {
    return parseFloat(simpleMatch[1])
  }
  
  return NaN
}

// 解析经纬度坐标并返回Leaflet格式的坐标数组
const parseCoordinates = (longitude: string, latitude: string): [number, number] | null => {
  const lng = parseCoordinate(longitude)
  const lat = parseCoordinate(latitude)
  
  if (isNaN(lng) || isNaN(lat) || lat < -90 || lat > 90 || lng < -180 || lng > 180) {
    return null
  }
  
  return [lat, lng]
}

const convertCoordinateToPixel = (longitude: string, latitude: string) => {
  // 简化的坐标转换，实际应该根据地图投影进行转换
  const lng = parseFloat(longitude.replace(/[°'"]/g, ''))
  const lat = parseFloat(latitude.replace(/[°'"]/g, ''))
  
  // 假设地图容器大小为800x600，东北地区经纬度范围
  const mapWidth = 800
  const mapHeight = 600
  const minLng = 115, maxLng = 135
  const minLat = 40, maxLat = 55
  
  const x = ((lng - minLng) / (maxLng - minLng)) * mapWidth
  const y = ((maxLat - lat) / (maxLat - minLat)) * mapHeight
  
  return { x, y }
}

const submitDisplay = () => {
  displayPoints.value = []
  currentDisplayType.value = displayType.value
  
  if (displayType.value === 'point') {
    // 显示点
    dataGroups.value.forEach(group => {
      group.subgroups.forEach(subgroup => {
        subgroup.data.forEach(item => {
          const { x, y } = convertCoordinateToPixel(item.东经, item.北纬)
          displayPoints.value.push({
            id: item.序号.toString(),
            name: item.保护单位名称,
            x,
            y,
            color: subgroup.color,
            shape: subgroup.shape
          })
        })
      })
    })
  } else if (displayType.value === 'line') {
    // 显示线（这里简化处理，实际需要在地图上绘制线条）
    ElMessage.info('线条显示功能需要在实际地图组件中实现')
  } else if (displayType.value === 'area') {
    // 显示面（这里简化处理，实际需要在地图上绘制多边形）
    ElMessage.info('面积显示功能需要在实际地图组件中实现')
  }
  
  showDisplayDialog.value = false
  ElMessage.success('展示设置已应用')
}

// 待分组数据管理
const togglePendingDataSelection = (item: DataItem) => {
  const index = selectedPendingData.value.findIndex(p => p.序号 === item.序号)
  if (index > -1) {
    selectedPendingData.value.splice(index, 1)
  } else {
    selectedPendingData.value.push(item)
  }
}

const addDataToSubgroup = (groupIndex: number, subIndex: number) => {
  if (selectedPendingData.value.length === 0) {
    ElMessage.warning('请先选择要添加的数据')
    return
  }
  
  // 将选中的待分组数据添加到指定子分组
  dataGroups.value[groupIndex].subgroups[subIndex].data.push(...selectedPendingData.value)
  
  // 从待分组数据中移除已添加的数据
  selectedPendingData.value.forEach(item => {
    const index = pendingData.value.findIndex(p => p.序号 === item.序号)
    if (index > -1) {
      pendingData.value.splice(index, 1)
    }
  })
  
  selectedPendingData.value = []
  ElMessage.success('数据已添加到子分组')
}

const removeDataFromSubgroup = (groupIndex: number, subIndex: number, item: DataItem) => {
  const subgroup = dataGroups.value[groupIndex].subgroups[subIndex]
  const index = subgroup.data.findIndex(d => d.序号 === item.序号)
  if (index > -1) {
    subgroup.data.splice(index, 1)
    // 将数据重新添加到待分组区域
    if (!pendingData.value.find(p => p.序号 === item.序号)) {
      pendingData.value.push(item)
    }
  }
}

const moveDataInSubgroup = (groupIndex: number, subIndex: number, itemIndex: number, direction: number) => {
  const subgroupData = dataGroups.value[groupIndex].subgroups[subIndex].data
  const newIndex = itemIndex + direction
  if (newIndex >= 0 && newIndex < subgroupData.length) {
    const temp = subgroupData[itemIndex]
    subgroupData[itemIndex] = subgroupData[newIndex]
    subgroupData[newIndex] = temp
  }
}

// 详情弹窗相关方法
const handleDetailSelectionChange = (selection: DataItem[]) => {
  detailSelectedData.value = selection
}

const handleSort = (field: string) => {
  if (sortField.value === field) {
    sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc'
  } else {
    sortField.value = field
    sortOrder.value = 'asc'
  }
}

const confirmDetailSelection = () => {
  if (detailSelectedData.value.length === 0) {
    ElMessage.warning('请选择要操作的数据')
    return
  }
  
  // 将选中的数据设置为待分组选中状态
  selectedPendingData.value = [...detailSelectedData.value]
  
  showDetailDialog.value = false
  detailSelectedData.value = []
  ElMessage.success(`已选择 ${selectedPendingData.value.length} 条数据`)
}

// 提交到地图显示
const submitToMap = () => {
  if (!canSubmit.value) {
    if (!hasData.value) {
      ElMessage.warning('请先选择数据并分组')
      return
    }
    if (!currentDisplayType.value) {
      ElMessage.warning('请先设定展示形式')
      return
    }
  }

  // 清除地图上现有的显示
  clearMapDisplay()
  
  // 根据展示形式显示数据
  if (currentDisplayType.value === 'point') {
    displayAsPoints()
  } else if (currentDisplayType.value === 'line') {
    displayAsLines()
  } else if (currentDisplayType.value === 'area') {
    displayAsAreas()
  }

  ElMessage.success('数据已成功显示在地图上')
}

// 清除地图显示
const clearMapDisplay = () => {
  if (!map) return
  
  // 只移除数据图层，保留底图
  dataLayers.forEach(layer => {
    map?.removeLayer(layer)
  })
  dataLayers = []
}

// 点显示
 const displayAsPoints = () => {
   if (!map) return
   
   dataGroups.value.forEach((group, groupIndex) => {
     group.subgroups.forEach((subgroup, subgroupIndex) => {
       const validPoints: Array<{lat: number, lng: number, item: any, index: number}> = []
       
       // 先收集所有有效坐标点
       subgroup.data.forEach((item, dataIndex) => {
         const lat = parseCoordinate(item.北纬)
         const lng = parseCoordinate(item.东经)
         
         if (!isNaN(lat) && !isNaN(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180) {
           validPoints.push({lat, lng, item, index: dataIndex})
         }
       })
       
       // 用于存储连接线
       const connectionLines: L.Polyline[] = []
       
       validPoints.forEach((point, pointIndex) => {
         const {lat, lng, item, index: dataIndex} = point
         
         console.log(`解析坐标: ${item.保护单位名称} - 原始: ${item.北纬}, ${item.东经} - 解析后: ${lat}, ${lng}`)
         
         // 延迟显示，按分组和数据顺序
         setTimeout(() => {
           // 根据子分组的形状创建不同的标记
           let marker
           if (subgroup.shape === 'circle') {
             marker = L.circleMarker([lat, lng], {
               radius: 8,
               fillColor: subgroup.color,
               color: '#fff',
               weight: 2,
               opacity: 1,
               fillOpacity: 0.8
             })
           } else {
             // 对于其他形状，使用DivIcon创建自定义标记
             const iconHtml = `
               <div style="
                 width: 16px;
                 height: 16px;
                 background-color: ${subgroup.color};
                 border: 2px solid #fff;
                 clip-path: ${getShapeClipPath(subgroup.shape)};
                 transform: translate(-50%, -50%);
               "></div>
             `
             const customIcon = L.divIcon({
               html: iconHtml,
               className: 'custom-marker',
               iconSize: [20, 20],
               iconAnchor: [10, 10]
             })
             marker = L.marker([lat, lng], { icon: customIcon })
           }
           
           marker.addTo(map!)
           dataLayers.push(marker)
           
           // 如果不是第一个点，创建与前一个点的连接线
           if (pointIndex > 0) {
             const prevPoint = validPoints[pointIndex - 1]
             const connectionLine = L.polyline(
               [[prevPoint.lat, prevPoint.lng], [lat, lng]], 
               {
                 color: subgroup.color,
                 weight: 2,
                 opacity: 0.6,
                 dashArray: '5, 5'
               }
             ).addTo(map!)
             
             connectionLines.push(connectionLine)
             dataLayers.push(connectionLine)
           }
           
           // 绑定悬浮和点击信息
           const popupContent = `
             <div style="font-size: 12px; min-width: 200px;">
               <strong style="color: ${subgroup.color}; font-size: 14px;">${item.保护单位名称 || '未知名称'}</strong><br>
               <div style="margin: 8px 0; padding: 4px; background: #f5f5f5; border-radius: 4px;">
                 <strong>分组信息:</strong> ${group.name} - ${subgroup.name}<br>
                 <strong>顺序:</strong> 第${pointIndex + 1}个点 (共${validPoints.length}个)<br>
                 <strong>类别:</strong> ${item.类别 || '未知类别'}<br>
                 <strong>年代:</strong> ${item.年代 || '未知年代'}<br>
                 <strong>地点:</strong> ${item.地点 || '未知地点'}<br>
                 <strong>公布批次:</strong> ${item.公布批次 || '未知批次'}<br>
                 <strong>坐标:</strong> ${lat.toFixed(4)}°N, ${lng.toFixed(4)}°E
               </div>
             </div>
           `
           
           marker.bindPopup(popupContent)
           
           // 添加悬浮提示
           marker.bindTooltip(`${group.name} - ${subgroup.name}: ${item.保护单位名称} (${pointIndex + 1}/${validPoints.length})`, {
             permanent: false,
             direction: 'top',
             offset: [0, -10]
           })
         }, (groupIndex * 2000) + (subgroupIndex * 1000) + (pointIndex * 400))
       })
     })
   })
 }
 
 // 线显示
 const displayAsLines = () => {
   if (!map) return
   
   dataGroups.value.forEach((group, groupIndex) => {
     group.subgroups.forEach((subgroup, subgroupIndex) => {
       if (subgroup.data.length < 2) return
       
       const validPoints: Array<{lat: number, lng: number, item: any, index: number}> = []
       
       // 先收集所有有效坐标点
       subgroup.data.forEach((item, dataIndex) => {
         const lat = parseCoordinate(item.北纬)
         const lng = parseCoordinate(item.东经)
         
         if (!isNaN(lat) && !isNaN(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180) {
           validPoints.push({lat, lng, item, index: dataIndex})
         }
       })
       
       if (validPoints.length >= 2) {
         // 用于存储连接线和点标记
         const connectionLines: L.Polyline[] = []
         const pointMarkers: L.Marker[] = []
         
         // 逐步显示点和连接线
         validPoints.forEach((point, pointIndex) => {
           const {lat, lng, item} = point
           
           setTimeout(() => {
             // 添加点标记
             const pointMarker = L.circleMarker([lat, lng], {
               radius: 6,
               fillColor: subgroup.color,
               color: '#fff',
               weight: 2,
               opacity: 1,
               fillOpacity: 1
             }).addTo(map!)
             
             pointMarkers.push(pointMarker)
             dataLayers.push(pointMarker)
             
             // 绑定点的信息
             pointMarker.bindTooltip(`线路点${pointIndex + 1}: ${item.保护单位名称}`, {
               permanent: false,
               direction: 'top',
               offset: [0, -10]
             })
             
             // 如果不是第一个点，创建与前一个点的连接线
             if (pointIndex > 0) {
               const prevPoint = validPoints[pointIndex - 1]
               const connectionLine = L.polyline(
                 [[prevPoint.lat, prevPoint.lng], [lat, lng]], 
                 {
                   color: subgroup.color,
                   weight: 4,
                   opacity: 0.8
                 }
               ).addTo(map!)
               
               connectionLines.push(connectionLine)
               dataLayers.push(connectionLine)
             }
             
             // 如果是最后一个点，添加整体线路的弹窗信息
             if (pointIndex === validPoints.length - 1) {
               setTimeout(() => {
                 // 创建一个透明的完整线路用于绑定弹窗
                 const fullPolyline = L.polyline(validPoints.map(p => [p.lat, p.lng]), {
                   color: 'transparent',
                   weight: 0
                 }).addTo(map!)
                 
                 dataLayers.push(fullPolyline)
                 
                 const pointDetails = validPoints.map(p => `${p.item.保护单位名称} (${p.item.地点})`)
                 
                 // 绑定详细信息弹窗
                 const popupContent = `
                   <div style="font-size: 12px; min-width: 250px;">
                     <strong style="color: ${subgroup.color}; font-size: 14px;">${group.name} - ${subgroup.name}</strong><br>
                     <div style="margin: 8px 0; padding: 4px; background: #f5f5f5; border-radius: 4px;">
                       <strong>线路信息:</strong><br>
                       包含 ${validPoints.length} 个连接点<br>
                       <strong>连接顺序:</strong><br>
                       ${pointDetails.map((detail, index) => `${index + 1}. ${detail}`).join('<br>')}
                     </div>
                   </div>
                 `
                 
                 fullPolyline.bindPopup(popupContent)
                 
                 // 添加悬浮提示
                 fullPolyline.bindTooltip(`${group.name} - ${subgroup.name}: 线路 (${validPoints.length}个点)`, {
                   permanent: false,
                   direction: 'center'
                 })
               }, 200)
             }
           }, (groupIndex * 2000) + (subgroupIndex * 1000) + (pointIndex * 500))
         })
       }
     })
   })
 }
 
 // 面显示
 const displayAsAreas = () => {
   if (!map) return
   
   dataGroups.value.forEach((group, groupIndex) => {
     group.subgroups.forEach((subgroup, subgroupIndex) => {
       if (subgroup.data.length < 3) return
       
       const validPoints: Array<{lat: number, lng: number, item: any, index: number}> = []
       
       // 先收集所有有效坐标点
       subgroup.data.forEach((item, dataIndex) => {
         const lat = parseCoordinate(item.北纬)
         const lng = parseCoordinate(item.东经)
         
         if (!isNaN(lat) && !isNaN(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180) {
           validPoints.push({lat, lng, item, index: dataIndex})
         }
       })
       
       if (validPoints.length >= 3) {
         // 用于存储边界线和点标记
         const boundaryLines: L.Polyline[] = []
         const pointMarkers: L.Marker[] = []
         
         // 逐步显示边界点和连接线
         validPoints.forEach((point, pointIndex) => {
           const {lat, lng, item} = point
           
           setTimeout(() => {
             // 添加边界点标记
             const pointMarker = L.circleMarker([lat, lng], {
               radius: 6,
               fillColor: subgroup.color,
               color: '#fff',
               weight: 2,
               opacity: 1,
               fillOpacity: 1
             }).addTo(map!)
             
             pointMarkers.push(pointMarker)
             dataLayers.push(pointMarker)
             
             // 绑定点的信息
             pointMarker.bindTooltip(`边界点${pointIndex + 1}: ${item.保护单位名称}`, {
               permanent: false,
               direction: 'top',
               offset: [0, -10]
             })
             
             // 如果不是第一个点，创建与前一个点的边界线
             if (pointIndex > 0) {
               const prevPoint = validPoints[pointIndex - 1]
               const boundaryLine = L.polyline(
                 [[prevPoint.lat, prevPoint.lng], [lat, lng]], 
                 {
                   color: subgroup.color,
                   weight: 3,
                   opacity: 0.8
                 }
               ).addTo(map!)
               
               boundaryLines.push(boundaryLine)
               dataLayers.push(boundaryLine)
             }
             
             // 如果是最后一个点，连接回第一个点形成封闭区域
             if (pointIndex === validPoints.length - 1) {
               setTimeout(() => {
                 const firstPoint = validPoints[0]
                 const closingLine = L.polyline(
                   [[lat, lng], [firstPoint.lat, firstPoint.lng]], 
                   {
                     color: subgroup.color,
                     weight: 3,
                     opacity: 0.8,
                     dashArray: '10, 5' // 用虚线表示封闭连接
                   }
                 ).addTo(map!)
                 
                 boundaryLines.push(closingLine)
                 dataLayers.push(closingLine)
                 
                 // 再延迟一点时间后创建填充区域
                 setTimeout(() => {
                   const points: [number, number][] = validPoints.map(p => [p.lat, p.lng])
                   const polygon = L.polygon(points, {
                     color: 'transparent',
                     weight: 0,
                     fillColor: subgroup.color,
                     fillOpacity: 0.3
                   }).addTo(map!)
                   
                   dataLayers.push(polygon)
                   
                   // 计算多边形中心点用于显示标签
                   const bounds = polygon.getBounds()
                   const center = bounds.getCenter()
                   
                   // 在面上添加分组名称标签
                   const labelMarker = L.marker([center.lat, center.lng], {
                     icon: L.divIcon({
                       html: `
                         <div style="
                           background: rgba(255, 255, 255, 0.9);
                           border: 2px solid ${subgroup.color};
                           border-radius: 4px;
                           padding: 4px 8px;
                           font-size: 12px;
                           font-weight: bold;
                           color: ${subgroup.color};
                           text-align: center;
                           white-space: nowrap;
                           box-shadow: 0 2px 4px rgba(0,0,0,0.2);
                         ">
                           ${group.name}<br>${subgroup.name}
                         </div>
                       `,
                       className: 'area-label',
                       iconSize: [100, 40],
                       iconAnchor: [50, 20]
                     })
                   }).addTo(map!)
                   
                   dataLayers.push(labelMarker)
                   
                   // 绑定详细信息弹窗
                   const pointDetails = validPoints.map(p => `${p.item.保护单位名称} (${p.item.地点})`)
                   const popupContent = `
                     <div style="font-size: 12px; min-width: 250px;">
                       <strong style="color: ${subgroup.color}; font-size: 14px;">${group.name} - ${subgroup.name}</strong><br>
                       <div style="margin: 8px 0; padding: 4px; background: #f5f5f5; border-radius: 4px;">
                         <strong>区域信息:</strong><br>
                         包含 ${validPoints.length} 个边界点<br>
                         <strong>边界点顺序:</strong><br>
                         ${pointDetails.map((detail, index) => `${index + 1}. ${detail}`).join('<br>')}<br>
                         <em>注: 按顺序连接形成封闭区域</em>
                       </div>
                     </div>
                   `
                   
                   polygon.bindPopup(popupContent)
                   labelMarker.bindPopup(popupContent)
                   
                   // 添加悬浮提示
                   polygon.bindTooltip(`${group.name} - ${subgroup.name}: 封闭区域`, {
                     permanent: false,
                     direction: 'center'
                   })
                   
                   labelMarker.bindTooltip(`${group.name} - ${subgroup.name}`, {
                     permanent: false,
                     direction: 'top',
                     offset: [0, -20]
                   })
                 }, 500)
               }, 300)
             }
           }, (groupIndex * 3000) + (subgroupIndex * 2000) + (pointIndex * 600))
         })
       }
     })
   })
 }

// 时空复现相关方法
const loadStudentData = () => {
  const student = mockStudentData.find(s => s.id === selectedStudentId.value)
  if (student) {
    // 深拷贝学生数据，避免修改原始数据
    selectedStudentData.value = JSON.parse(JSON.stringify(student))
    // 初始化所有分组为未选中状态
    selectedStudentData.value.groups.forEach(group => {
      group.selected = false
    })
  } else {
    selectedStudentData.value = null
  }
}

const updateGroupSelection = (groupIndex: number) => {
  // 这个方法在模板中被调用，用于更新分组选择状态
  // 实际的状态更新由 v-model 自动处理
}

const getDisplayTypeName = (type: string) => {
  const option = displayOptions.find(opt => opt.value === type)
  return option ? option.title : type
}

const getShapeName = (shape: string) => {
  const shapeNames: Record<string, string> = {
    circle: '圆形',
    square: '方形',
    triangle: '三角形',
    star: '星形',
    diamond: '菱形'
  }
  return shapeNames[shape] || shape
}

const reproduceStudentExperiment = async () => {
  if (!selectedStudentData.value || !hasSelectedGroups.value) {
    ElMessage.warning('请选择要复现的分组')
    return
  }

  // 关闭对话框
  showReproductionDialog.value = false
  
  // 清除当前地图上的所有数据图层
  clearMapDisplay()

  // 获取选中的分组数据
  const selectedGroups = selectedStudentData.value.groups.filter(group => group.selected)
  
  // 设置当前显示类型
  currentDisplayType.value = selectedStudentData.value.displayType

  ElMessage.info(`开始复现 ${selectedStudentData.value.name} 的实验结果...`)

  // 依次显示每个分组的数据
  for (let i = 0; i < selectedGroups.length; i++) {
    const group = selectedGroups[i]
    
    // 添加当前分组到数据分组中
    dataGroups.value.push({
      id: group.id,
      name: group.name,
      subgroups: group.subgroups
    })

    // 显示当前分组的数据
    await displayGroupData(group, selectedStudentData.value.displayType)
    
    // 显示进度消息
    ElMessage.success(`已显示分组 "${group.name}" (${i + 1}/${selectedGroups.length})`)
    
    // 等待一段时间再显示下一个分组
    if (i < selectedGroups.length - 1) {
      await new Promise(resolve => setTimeout(resolve, 1500))
    }
  }
  
  ElMessage.success(`复现完成！共显示 ${selectedGroups.length} 个分组 (${getDisplayTypeName(selectedStudentData.value.displayType)})`)
}

// 显示单个分组的数据
const displayGroupData = async (group, displayType) => {
  // 根据显示类型处理分组数据
  switch (displayType) {
    case 'point':
      return await displayGroupAsPoints(group)
    case 'line':
      return await displayGroupAsLines(group)
    case 'area':
      return await displayGroupAsAreas(group)
  }
}

// 将分组显示为点
const displayGroupAsPoints = (group) => {
  return new Promise((resolve) => {
    let totalDelay = 0
    
    group.subgroups.forEach((subgroup, subgroupIndex) => {
      subgroup.data.forEach((item, itemIndex) => {
        const coords = parseCoordinates(item.东经, item.北纬)
        if (coords) {
          setTimeout(() => {
            let marker
            
            // 根据子分组的形状创建不同的标记
            if (subgroup.shape === 'circle') {
              marker = L.circleMarker(coords, {
                radius: 8,
                fillColor: subgroup.color,
                color: '#fff',
                weight: 2,
                opacity: 1,
                fillOpacity: 0.8
              })
            } else {
              // 对于其他形状，使用DivIcon
              const iconHtml = `
                <div style="
                  width: 16px;
                  height: 16px;
                  background-color: ${subgroup.color};
                  border: 2px solid #fff;
                  clip-path: ${getShapeClipPath(subgroup.shape)};
                  box-shadow: 0 2px 4px rgba(0,0,0,0.3);
                "></div>
              `
              
              const customIcon = L.divIcon({
                html: iconHtml,
                className: 'custom-marker',
                iconSize: [20, 20],
                iconAnchor: [10, 10]
              })
              
              marker = L.marker(coords, { icon: customIcon })
            }
            
            marker.bindPopup(`
              <div style="font-family: '微软雅黑'; max-width: 200px;">
                <h4 style="margin: 0 0 8px 0; color: ${subgroup.color};">${item.保护单位名称}</h4>
                <p style="margin: 2px 0; font-size: 12px;"><strong>分组:</strong> ${group.name}</p>
                <p style="margin: 2px 0; font-size: 12px;"><strong>子分组:</strong> ${subgroup.name}</p>
                <p style="margin: 2px 0; font-size: 12px;"><strong>形状:</strong> ${getShapeName(subgroup.shape)}</p>
                <p style="margin: 2px 0; font-size: 12px;"><strong>类别:</strong> ${item.类别}</p>
                <p style="margin: 2px 0; font-size: 12px;"><strong>年代:</strong> ${item.年代}</p>
                <p style="margin: 2px 0; font-size: 12px;"><strong>地点:</strong> ${item.地点}</p>
              </div>
            `)
            
            marker.bindTooltip(item.保护单位名称, {
              permanent: false,
              direction: 'top',
              offset: [0, -10]
            })
            
            marker.addTo(map!)
            dataLayers.push(marker)
          }, totalDelay)
          
          totalDelay += 300 // 每个点间隔300ms
        }
      })
    })
    
    // 等待所有点显示完成
    setTimeout(resolve, totalDelay + 500)
  })
}

// 将分组显示为线
const displayGroupAsLines = (group) => {
  return new Promise((resolve) => {
    let totalDelay = 0
    
    group.subgroups.forEach((subgroup, subgroupIndex) => {
      const validPoints = []
      
      // 先收集所有有效坐标点
      subgroup.data.forEach((item, dataIndex) => {
        const coords = parseCoordinates(item.东经, item.北纬)
        if (coords) {
          validPoints.push({coords, item, index: dataIndex})
        }
      })
      
      if (validPoints.length >= 2) {
        // 逐步显示点和连接线
        validPoints.forEach((point, pointIndex) => {
          setTimeout(() => {
            // 添加点标记
            const pointMarker = L.circleMarker(point.coords, {
              radius: 6,
              fillColor: subgroup.color,
              color: '#fff',
              weight: 2,
              opacity: 1,
              fillOpacity: 1
            })
            
            pointMarker.bindTooltip(`点${pointIndex + 1}: ${point.item.保护单位名称}`, {
              permanent: false,
              direction: 'top',
              offset: [0, -10]
            })
            
            pointMarker.addTo(map!)
            dataLayers.push(pointMarker)
            
            // 如果不是第一个点，创建与前一个点的连接线
            if (pointIndex > 0) {
              const prevPoint = validPoints[pointIndex - 1]
              const line = L.polyline([prevPoint.coords, point.coords], {
                color: subgroup.color,
                weight: 4,
                opacity: 0.8
              })
              
              line.addTo(map!)
              dataLayers.push(line)
            }
            
            // 如果是最后一个点，添加整体线路的弹窗信息
            if (pointIndex === validPoints.length - 1) {
              setTimeout(() => {
                const fullPolyline = L.polyline(validPoints.map(p => p.coords), {
                  color: 'transparent',
                  weight: 0
                })
                
                const pointDetails = validPoints.map(p => `${p.item.保护单位名称} (${p.item.地点})`)
                
                fullPolyline.bindPopup(`
                  <div style="font-family: '微软雅黑'; max-width: 250px;">
                    <h4 style="margin: 0 0 8px 0; color: ${subgroup.color};">${group.name} - ${subgroup.name}</h4>
                    <p style="margin: 2px 0; font-size: 12px;"><strong>线路信息:</strong></p>
                    <p style="margin: 2px 0; font-size: 12px;">包含 ${validPoints.length} 个数据点</p>
                    <div style="margin: 8px 0; padding: 4px; background: #f5f5f5; border-radius: 4px;">
                      <strong>连接顺序:</strong><br>
                      ${pointDetails.map((detail, index) => `${index + 1}. ${detail}`).join('<br>')}
                    </div>
                  </div>
                `)
                
                fullPolyline.addTo(map!)
                dataLayers.push(fullPolyline)
              }, 200)
            }
          }, totalDelay)
          
          totalDelay += 500 // 每个点和线间隔500ms
        })
      }
    })
    
    // 等待所有线显示完成
    setTimeout(resolve, totalDelay + 1000)
  })
}

// 将分组显示为面
const displayGroupAsAreas = (group) => {
  return new Promise((resolve) => {
    let totalDelay = 0
    
    group.subgroups.forEach((subgroup, subgroupIndex) => {
      const validPoints = []
      
      // 先收集所有有效坐标点
      subgroup.data.forEach((item, dataIndex) => {
        const coords = parseCoordinates(item.东经, item.北纬)
        if (coords) {
          validPoints.push({coords, item, index: dataIndex})
        }
      })
      
      if (validPoints.length >= 3) {
        // 逐步显示点和边界
        validPoints.forEach((point, pointIndex) => {
          setTimeout(() => {
            // 添加点标记
            const pointMarker = L.circleMarker(point.coords, {
              radius: 6,
              fillColor: subgroup.color,
              color: '#fff',
              weight: 2,
              opacity: 1,
              fillOpacity: 1
            })
            
            pointMarker.bindTooltip(`顶点${pointIndex + 1}: ${point.item.保护单位名称}`, {
              permanent: false,
              direction: 'top',
              offset: [0, -10]
            })
            
            pointMarker.addTo(map!)
            dataLayers.push(pointMarker)
            
            // 如果不是第一个点，创建与前一个点的连接线
            if (pointIndex > 0) {
              const prevPoint = validPoints[pointIndex - 1]
              const line = L.polyline([prevPoint.coords, point.coords], {
                color: subgroup.color,
                weight: 2,
                opacity: 0.8,
                dashArray: '5, 5'
              })
              
              line.addTo(map!)
              dataLayers.push(line)
            }
            
            // 如果是最后一个点，连接到第一个点形成闭合，并创建面
            if (pointIndex === validPoints.length - 1) {
              setTimeout(() => {
                // 连接最后一个点到第一个点
                const closingLine = L.polyline([point.coords, validPoints[0].coords], {
                  color: subgroup.color,
                  weight: 2,
                  opacity: 0.8,
                  dashArray: '5, 5'
                })
                
                closingLine.addTo(map!)
                dataLayers.push(closingLine)
                
                // 创建填充面
                setTimeout(() => {
                  const polygon = L.polygon(validPoints.map(p => p.coords), {
                    color: subgroup.color,
                    fillColor: subgroup.color,
                    fillOpacity: 0.3,
                    weight: 3
                  })
                  
                  const pointDetails = validPoints.map(p => `${p.item.保护单位名称} (${p.item.地点})`)
                  
                  polygon.bindPopup(`
                    <div style="font-family: '微软雅黑'; max-width: 250px;">
                      <h4 style="margin: 0 0 8px 0; color: ${subgroup.color};">${group.name} - ${subgroup.name}</h4>
                      <p style="margin: 2px 0; font-size: 12px;"><strong>区域信息:</strong></p>
                      <p style="margin: 2px 0; font-size: 12px;">包含 ${validPoints.length} 个顶点</p>
                      <div style="margin: 8px 0; padding: 4px; background: #f5f5f5; border-radius: 4px;">
                        <strong>顶点列表:</strong><br>
                        ${pointDetails.map((detail, index) => `${index + 1}. ${detail}`).join('<br>')}
                      </div>
                    </div>
                  `)
                  
                  polygon.addTo(map!)
                  dataLayers.push(polygon)
                }, 300)
              }, 300)
            }
          }, totalDelay)
          
          totalDelay += 500 // 每个点间隔500ms
        })
      }
    })
    
    // 等待所有面显示完成
    setTimeout(resolve, totalDelay + 1500)
  })
}

// 生命周期
onMounted(() => {
  initMap()
})
</script>

<style scoped>
.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.detail-btn {
  margin-right: 8px;
}

.data-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 8px;
  margin: 2px 0;
  background: #f5f5f5;
  border-radius: 4px;
  font-size: 12px;
}

.item-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-controls {
  display: flex;
  gap: 2px;
  margin-left: 8px;
}

.move-btn {
  padding: 2px 4px;
  min-width: 20px;
  height: 20px;
}

.remove-data-btn {
  padding: 2px 4px;
  min-width: 20px;
  height: 20px;
  color: #f56c6c;
}

.detail-dialog .el-dialog__body {
  padding: 10px 20px;
}

.detail-table-section .section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  font-size: 16px;
  font-weight: 600;
}

.detail-table-section .data-count {
  color: #909399;
  font-weight: normal;
  margin-left: auto;
}

/* 自定义地图标记样式 */
.custom-marker {
  background: transparent !important;
  border: none !important;
}

.area-label {
  background: transparent !important;
  border: none !important;
}
.app-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(135deg, #F5E6D3 0%, #E8D5B7 100%);
  font-family: 'Microsoft YaHei', '微软雅黑', serif;
}

.header {
  height: 60px;
  background: linear-gradient(135deg, #8B4513 0%, #A0522D 50%, #CD853F 100%);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
  box-shadow: 0 4px 12px rgba(139, 69, 19, 0.3);
  border-bottom: 2px solid #D4AF37;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 15px;
}

.logo {
  display: flex;
  align-items: center;
}

.logo-img {
  height: 40px;
  width: auto;
  object-fit: contain;
}

.platform-title {
  color: #F5DEB3;
  font-size: 20px;
  font-weight: bold;
  margin: 0;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}

.header-right {
  display: flex;
  align-items: center;
  gap: 20px;
}

.current-display {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  background: rgba(245, 222, 179, 0.2);
  border: 1px solid #D4AF37;
  border-radius: 6px;
}

.display-label {
  color: #F5DEB3;
  font-size: 12px;
  font-weight: 500;
}

.display-icon {
  display: flex;
  align-items: center;
}

.display-text {
  color: #F5DEB3;
  font-size: 12px;
  font-weight: 500;
}

.analysis-btn {
  background: linear-gradient(135deg, #D4AF37 0%, #B8860B 100%);
  border: 1px solid #DAA520;
  color: #8B4513;
  font-weight: bold;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.analysis-btn:hover {
  background: linear-gradient(135deg, #FFD700 0%, #D4AF37 100%);
  transform: translateY(-1px);
}

.reproduction-btn {
  background: linear-gradient(135deg, #8B4513 0%, #A0522D 100%);
  border: 1px solid #654321;
  color: #F5DEB3;
  font-weight: 500;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
  margin-left: 12px;
}

.reproduction-btn:hover {
  background: linear-gradient(135deg, #A0522D 0%, #CD853F 100%);
  transform: translateY(-1px);
  color: #FFFACD;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.username {
  color: #F5DEB3;
  font-weight: 500;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

.main-content {
  flex: 1;
  display: flex;
  gap: 20px;
  padding: 20px;
  overflow: hidden;
}

.map-container {
  flex: 1;
  position: relative;
  background: #FFF8DC;
  border: 3px solid #D4AF37;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(139, 69, 19, 0.2);
  overflow: hidden;
}

.map {
  width: 100%;
  height: 100%;
  border-radius: 8px;
}

.map-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.map-point {
  position: absolute;
  width: 12px;
  height: 12px;
  border: 2px solid #8B4513;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  box-shadow: 0 2px 6px rgba(139, 69, 19, 0.4);
}

.sidebar {
  width: 380px;
  background: linear-gradient(135deg, #FFF8DC 0%, #F5E6D3 100%);
  border: 2px solid #D4AF37;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(139, 69, 19, 0.2);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.pending-data-section {
  border-bottom: 2px solid #D4AF37;
  background: linear-gradient(135deg, #FFFACD 0%, #FFF8DC 100%);
}

.groups-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.section-header {
  padding: 15px 20px;
  border-bottom: 1px solid #DDD;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(135deg, #F0E68C 0%, #DAA520 100%);
}

.section-header h4 {
  margin: 0;
  color: #8B4513;
  font-weight: bold;
  text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.5);
}

.data-count {
  background: #8B4513;
  color: #F5DEB3;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: bold;
}

.pending-data-list {
  max-height: 150px;
  overflow-y: auto;
  padding: 10px;
}

.pending-data-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  margin-bottom: 5px;
  background: #FFFACD;
  border: 1px solid #DDD;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.pending-data-item:hover {
  background: #F0E68C;
  border-color: #D4AF37;
  transform: translateX(2px);
}

.pending-data-item.selected {
  background: #DAA520;
  border-color: #B8860B;
  color: white;
}

.item-name {
  flex: 1;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.groups-container {
  flex: 1;
  padding: 15px;
  overflow-y: auto;
}

.group-item {
  margin-bottom: 15px;
  border: 2px solid #D4AF37;
  border-radius: 8px;
  padding: 12px;
  background: linear-gradient(135deg, #FFFACD 0%, #F5E6D3 100%);
  box-shadow: 0 4px 8px rgba(139, 69, 19, 0.1);
}

.group-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.group-name-input {
  flex: 1;
}

.group-controls {
  display: flex;
  gap: 4px;
}

.subgroups-container {
  margin-left: 8px;
}

.subgroup-item {
  margin-bottom: 12px;
  border: 1px solid #DDD;
  border-radius: 6px;
  padding: 10px;
  background: #FFFACD;
  position: relative;
}

.subgroup-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}

.subgroup-name-input {
  flex: 1;
  min-width: 120px;
}

.subgroup-style {
  display: flex;
  gap: 4px;
  align-items: center;
}

.subgroup-controls {
  display: flex;
  gap: 4px;
}

.subgroup-data {
  max-height: 100px;
  overflow-y: auto;
  margin-bottom: 8px;
}

.data-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  background: #F0E68C;
  border: 1px solid #DAA520;
  border-radius: 4px;
  margin-bottom: 4px;
  font-size: 12px;
  cursor: pointer;
}

.remove-data-btn {
  padding: 2px 4px !important;
  min-height: auto !important;
  color: #8B4513 !important;
}

.add-data-btn, .add-subgroup-btn {
  width: 100%;
  margin-top: 8px;
  border: 1px dashed #D4AF37 !important;
  color: #8B4513 !important;
  background: transparent !important;
}

.add-data-btn:hover, .add-subgroup-btn:hover {
  background: #F0E68C !important;
  border-color: #B8860B !important;
}

.sidebar-footer {
  padding: 15px 20px;
  border-top: 2px solid #D4AF37;
  background: linear-gradient(135deg, #F0E68C 0%, #DAA520 100%);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 15px;
}

.submit-button-container {
  display: flex;
  align-items: center;
}

.submit-btn {
  padding: 10px 20px !important;
  font-size: 14px !important;
  font-weight: 500 !important;
  height: auto !important;
  min-width: 100px;
  background: linear-gradient(135deg, #8B4513 0%, #A0522D 100%) !important;
  border: 1px solid #654321 !important;
  color: #F5DEB3 !important;
  box-shadow: 0 4px 12px rgba(139, 69, 19, 0.3) !important;
  border-radius: 8px !important;
  transition: all 0.3s ease !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

.submit-btn:hover {
  background: linear-gradient(135deg, #A0522D 0%, #CD853F 100%) !important;
  transform: translateY(-2px) !important;
  box-shadow: 0 6px 16px rgba(139, 69, 19, 0.4) !important;
}

.submit-btn:disabled {
  background: linear-gradient(135deg, #999 0%, #666 100%) !important;
  border-color: #555 !important;
  color: #ccc !important;
  transform: none !important;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2) !important;
}

.submit-btn span {
  margin-left: 6px;
}

.data-dialog-content {
  max-height: 700px;
  overflow-y: auto;
}

.filter-section, .table-section {
  margin-bottom: 24px;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 16px 0;
  color: #8B4513;
  font-size: 16px;
  font-weight: bold;
  padding-bottom: 8px;
  border-bottom: 2px solid #D4AF37;
}

.filter-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.filter-item label {
  font-size: 13px;
  color: #8B4513;
  font-weight: 500;
}

.filter-controls {
  padding: 20px;
  background: linear-gradient(135deg, #FFFACD 0%, #FFF8DC 100%);
  border-radius: 8px;
  border: 2px solid #D4AF37;
  box-shadow: 0 4px 8px rgba(139, 69, 19, 0.1);
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 16px 0;
}

.display-options {
  padding: 20px 0;
}

.display-radio-group {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.display-option {
  width: 100%;
  margin: 0 !important;
  cursor: pointer;
  transition: all 0.3s ease;
}

.option-content {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 20px;
  border: 2px solid #DDD;
  border-radius: 12px;
  background: linear-gradient(135deg, #FFFACD 0%, #FFF8DC 100%);
  transition: all 0.3s ease;
  cursor: pointer;
  position: relative;
}

.display-option.is-checked .option-content {
  border-color: #D4AF37;
  background: linear-gradient(135deg, #F0E68C 0%, #DAA520 30%, #FFFACD 100%);
  box-shadow: 0 6px 16px rgba(212, 175, 55, 0.3);
  transform: translateY(-2px);
}

.option-radio {
  flex-shrink: 0;
  margin-right: 10px;
}

.option-icon {
  flex-shrink: 0;
  padding: 8px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.option-text {
  flex: 1;
}

.option-title {
  font-weight: bold;
  color: #8B4513;
  margin-bottom: 6px;
  font-size: 16px;
}

.option-desc {
  font-size: 14px;
  color: #666;
  line-height: 1.4;
}

.map-status {
  position: absolute;
  bottom: 20px;
  right: 20px;
  background: linear-gradient(135deg, #8B4513 0%, #A0522D 100%);
  border: 2px solid #D4AF37;
  border-radius: 8px;
  padding: 10px 15px;
  box-shadow: 0 4px 12px rgba(139, 69, 19, 0.3);
  z-index: 1000;
}

.status-content {
  display: flex;
  align-items: center;
  gap: 8px;
}

.status-label {
  color: #F5DEB3;
  font-size: 13px;
  font-weight: bold;
}

.status-icon {
  display: flex;
  align-items: center;
}

.status-text {
  color: #F5DEB3;
  font-size: 13px;
  font-weight: bold;
}

/* 滚动条样式 */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: #F5E6D3;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: #D4AF37;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: #B8860B;
}

/* Element Plus 组件样式覆盖 */
:deep(.el-button--primary) {
  background: linear-gradient(135deg, #D4AF37 0%, #B8860B 100%);
  border-color: #DAA520;
  color: #8B4513;
  font-weight: bold;
}

:deep(.el-button--primary:hover) {
  background: linear-gradient(135deg, #FFD700 0%, #D4AF37 100%);
  border-color: #FFD700;
}

:deep(.el-dialog) {
  border: 2px solid #D4AF37;
  border-radius: 12px;
}

:deep(.el-dialog__header) {
  background: linear-gradient(135deg, #F0E68C 0%, #DAA520 100%);
  border-bottom: 1px solid #D4AF37;
  border-radius: 10px 10px 0 0;
}

:deep(.el-dialog__title) {
  color: #8B4513;
  font-weight: bold;
}

:deep(.el-table) {
  border: 1px solid #D4AF37;
  border-radius: 6px;
}

:deep(.el-table th) {
  background: #F0E68C;
  color: #8B4513;
  font-weight: bold;
}

:deep(.el-input__wrapper) {
  border: 1px solid #DDD;
  border-radius: 4px;
}

/* 时空复现对话框样式 */
.reproduction-dialog :deep(.el-dialog) {
  max-width: 1200px;
}

.reproduction-content {
  padding: 20px 0;
}

.student-selection {
  margin-bottom: 30px;
}

.student-data-preview {
  margin-top: 20px;
}

.student-info {
  background: linear-gradient(135deg, #FFFACD 0%, #FFF8DC 100%);
  border: 2px solid #D4AF37;
  border-radius: 8px;
  padding: 15px;
  margin-bottom: 20px;
}

.student-info p {
  margin: 5px 0;
  color: #8B4513;
  font-size: 14px;
}

.groups-preview {
  max-height: 400px;
  overflow-y: auto;
}

.group-preview {
  border: 2px solid #DDD;
  border-radius: 8px;
  margin-bottom: 15px;
  background: #FAFAFA;
  transition: all 0.3s ease;
}

.group-preview:hover {
  border-color: #D4AF37;
  box-shadow: 0 4px 8px rgba(212, 175, 55, 0.2);
}

.group-header {
  padding: 12px 15px;
  background: linear-gradient(135deg, #F0E68C 0%, #DAA520 30%, #FFFACD 100%);
  border-bottom: 1px solid #DDD;
  border-radius: 6px 6px 0 0;
}

.group-checkbox {
  font-size: 16px;
  color: #8B4513;
}

.subgroups-preview {
  padding: 15px;
}

.subgroup-preview {
  background: white;
  border: 1px solid #E0E0E0;
  border-radius: 6px;
  padding: 12px;
  margin-bottom: 10px;
}

.subgroup-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.subgroup-name {
  font-weight: bold;
  color: #8B4513;
  font-size: 14px;
}

.subgroup-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: #666;
}

.color-indicator {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px #ddd;
}

.shape-indicator {
  background: #F5F5F5;
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 11px;
}

.data-count {
  color: #999;
  font-style: italic;
}

.subgroup-data {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  align-items: center;
}

.more-data {
  color: #999;
  font-size: 12px;
  font-style: italic;
}

:deep(.el-input__wrapper:hover) {
  border-color: #D4AF37;
}

:deep(.el-input__wrapper.is-focus) {
  border-color: #B8860B;
  box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.2);
}
</style>